package com.xiaoyu.lanling.feature.login.activity

import `in`.srain.cube.util.TimeUtils
import `in`.srain.cube.util.UTUtil
import android.app.ProgressDialog
import android.os.Bundle
import androidx.viewpager.widget.ViewPager
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.xiaoyu.base.AppConfig
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.base.event.AppEventBus
import com.xiaoyu.base.event.SimpleEventHandler
import com.xiaoyu.base.utils.ListUtil
import com.xiaoyu.base.utils.RxUtils
import com.xiaoyu.base.utils.extensions.setOnClickDebounceListener
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.activity.base.AppCompatToolbarActivity
import com.xiaoyu.lanling.common.Constant
import com.xiaoyu.lanling.common.config.WeChatConfig
import com.xiaoyu.lanling.data.ConfigData
import com.xiaoyu.lanling.event.login.LoginCellphoneClickWechatLoginEvent
import com.xiaoyu.lanling.event.login.LoginEvent
import com.xiaoyu.lanling.event.login.WeChatAuthEvent
import com.xiaoyu.lanling.event.login.WechatLoginEvent
import com.xiaoyu.lanling.feature.login.data.LoginData
import com.xiaoyu.lanling.feature.login.fragment.LoginBannerFragment
import com.xiaoyu.lanling.feature.view.ScaleCircleNavigator
import com.xiaoyu.lanling.router.Router
import com.xiaoyu.lanling.router.deeplink.DeepLinkRouter
import com.xiaoyu.lanling.view.FragmentAdapter
import com.xiaoyu.lanling.view.OnShowFragment
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.activity_login.privacy_text
import kotlinx.android.synthetic.main.activity_login.wechat_login_button
import net.lucode.hackware.magicindicator.ViewPagerHelper
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.concurrent.TimeUnit

class LoginActivity : AppCompatToolbarActivity() {

    private val requestTag = Any()
    private var isAutoPlay: Boolean = true
    private var mViewPagerDisposable: Disposable? = null

    private val progressDialog by lazy {
        val dialog = ProgressDialog(this)
        dialog.setMessage(AppContext.getString(R.string.common_loading_please_wait))
        dialog
    }

    override fun onCreateSafelyAfterAppFinishInit(savedInstanceState: Bundle?) {
        super.onCreateSafelyAfterAppFinishInit(savedInstanceState)
        setLightStatusBar()
        setContentView(R.layout.activity_login)

        initViewPager()
        initBind()
        initEvent()
        logEventForEnter()
    }

    override fun onDestroy() {
        super.onDestroy()
        mViewPagerDisposable?.dispose()
    }

    private fun initBind() {
        cellphone_login_button.setOnClickDebounceListener {
            logEventForClick("cellphone")
            Router.instance.gotoLoginCellphoneActivity(this)
        }
        wechat_login_button.setOnClickDebounceListener {
            loginViaWeChatSDK()
        }
        user_text.setOnClickDebounceListener {
            val url = ConfigData.getInstance().getUrl("userProtocol")
            DeepLinkRouter.getInstance().dispatch(this, url)
        }
        privacy_text.setOnClickDebounceListener {
            val url = ConfigData.getInstance().getUrl("privacyProtocol")
            DeepLinkRouter.getInstance().dispatch(this, url)
        }
    }

    private fun initEvent() {
        AppEventBus.bindContainerAndHandler(this, object : SimpleEventHandler() {
            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: WeChatAuthEvent) {
                if (event.isSuccess) {
                    showDialog()
                    LoginData.wechatLogin(requestTag, event.code)
                } else {
                    GlobalUI.getInstance().showToast(getString(R.string.login_wechat_auth_failure))
                }
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: WechatLoginEvent) {
                if (event.isNotFromThisRequestTag(requestTag)) {
                    return
                }
                dismissDialog()
                if (event.isFailed) {
                    return
                }
                dispatchLogin(event)
            }

            @Subscribe(threadMode = ThreadMode.MAIN)
            fun onEvent(event: LoginCellphoneClickWechatLoginEvent) {
                loginViaWeChatSDK()
            }
        })
    }

    private fun initViewPager() {
        val fragments = arrayListOf<OnShowFragment>().apply {
            add(LoginBannerFragment.create(supportFragmentManager, 0))
            add(LoginBannerFragment.create(supportFragmentManager, 1))
            add(LoginBannerFragment.create(supportFragmentManager, 2))
        }

        val titles: MutableList<CharSequence> = ListUtil.convertListWithIndex(fragments) { index, _ -> index.toString() }
        val bannerCount = fragments.size

        val fragmentAdapter = FragmentAdapter(supportFragmentManager, fragments, titles)
        view_pager.adapter = fragmentAdapter
        view_pager.offscreenPageLimit = bannerCount
        view_pager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
            override fun onPageSelected(position: Int) {
                fragmentAdapter.tryShowOnIndex(position)
            }

            override fun onPageScrollStateChanged(state: Int) {
                when (state) {
                    ViewPager.SCROLL_STATE_IDLE -> isAutoPlay = true
                    ViewPager.SCROLL_STATE_DRAGGING -> isAutoPlay = false
                    ViewPager.SCROLL_STATE_SETTLING -> isAutoPlay = true
                }
            }
        })
        isAutoPlay = fragments.size >= 2
        initMagicIndicator(bannerCount)
        initViewPagerDisposable()
    }

    private fun initMagicIndicator(size: Int) {
        val scaleCircleNavigator = ScaleCircleNavigator(this)
        scaleCircleNavigator.setCircleCount(size)
        scaleCircleNavigator.setNormalCircleColor(AppContext.getColor(R.color.scale_circle_navigator_normal))
        scaleCircleNavigator.setSelectedCircleColor(AppContext.getColor(R.color.scale_circle_navigator_select_secondary_dark))
        scaleCircleNavigator.setCircleClickListener { index -> view_pager.currentItem = index }
        magic_indicator.navigator = scaleCircleNavigator
        ViewPagerHelper.bind(magic_indicator, view_pager)
    }

    private fun initViewPagerDisposable() {
        mViewPagerDisposable?.dispose()
        mViewPagerDisposable = Observable.interval(3 * TimeUtils.MILLIS_IN_SECOND, TimeUnit.MILLISECONDS)
                .compose(RxUtils.ioToMainObservableScheduler())
                .filter {
                    view_pager?.let {
                        return@filter isAutoPlay && it.childCount > 0
                    }
                    return@filter false
                }
                .subscribe({
                    view_pager?.let {
                        it.currentItem = (it.currentItem + 1) % it.childCount
                    }
                }, { it.printStackTrace() })
    }

    private fun loginViaWeChatSDK() {
        logEventForClick("wechat")
        val iwxapi = WXAPIFactory.createWXAPI(this, AppConfig.wechatAppId(), true)
        if (!iwxapi.isWXAppInstalled) {
            GlobalUI.getInstance().showToast(R.string.wechat_not_installed)
            return
        }
        iwxapi.registerApp(AppConfig.wechatAppId())
        val req = SendAuth.Req()
        req.state = WeChatConfig.req_state
        req.scope = WeChatConfig.req_scope
        iwxapi.sendReq(req)
    }

    private fun dispatchLogin(event: WechatLoginEvent) {
        when {
            event.status == LoginEvent.STATUS_DISABLE -> Router.instance.gotoLockActivity(this, wehchatOpenId = event.openId)
            event.hasSetProfile -> Router.instance.gotoMainActivityForNew(this, 0)
            else -> Router.instance.gotoRegisterActivity(this, event.name, Constant.LoginType.WECHAT)
        }
        logForDispatchLogin(event.hasSetProfile, event.status)
    }

    fun showDialog() {
        if (this.isFinishing || this.isDestroyed) {
            return
        }
        progressDialog.show()
    }

    fun dismissDialog() {
        progressDialog.dismiss()
    }

    private fun logEventForEnter() {
        UTUtil.getInstance().logEvent("enter_login_page")
        UTUtil.getInstance().flushLogEvent()
    }

    private fun logEventForClick(loginType: String) {
        val params = Bundle()
        params.putString("login_type", loginType)
        UTUtil.getInstance().logEvent("login_click", params)
        UTUtil.getInstance().flushLogEvent()
    }

    private fun logForDispatchLogin(registered: Boolean, status: String) {
        val params = Bundle()
        params.putBoolean("registered", registered)
        params.putString("status", status)
        UTUtil.getInstance().logEvent("login_auth_code_confirm", params)
        UTUtil.getInstance().flushLogEvent()
    }
}